package cz.tomasdvorak.cars.wicket.components.table;

import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.IModel;

import java.util.Iterator;
import java.util.List;

/**
 * Like {@link org.apache.wicket.markup.repeater.data.ListDataProvider}, but:
 * <ul>
 *   <li>supports sorting through inheritance from {@link SortableDataProvider}</li>
 *   <li>the list is loaded lazily (user must implement {@link #loadData()}) and is detached
 *     every time (and then loaded again, supporting changes in content)</li>
 * </ul>
 * <p/>
 * <b>DO NOT USE </b> for large datasets, the list is always loaded in its entirety!
 */
public abstract class AbstractListDataProvider<T> extends SortableDataProvider<T> {
    private transient List<T> list;

    public final Iterator<? extends T> iterator(int first, int count) {
        checkData();
        int last = first + count;
        if (last > list.size()) {
            last = list.size();
        }
        return list.subList(first, last).iterator();
    }

    public final int size() {
        checkData();
        return list.size();
    }

    public IModel<T> model(final T object) {
        return new AbstractReadOnlyModel<T>() {
            public T getObject() {
                return object;
            }
        };
    }

    public final void detach() {
        list = null;
    }

    private void checkData() {
        if (list != null) {
            return;
        }

        try {
            list = loadData();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    protected abstract List<T> loadData() throws Exception;
}
